/**
 * C Compiler Compatible Adapter / C 语言编译器兼容性适配
 *
 * 编译器常见内置宏及其含义:
 *   __GNUC__             // GNU GCC Compiler
 *   __ARMCC_VERSION      // ARM Keil C-Compiler
 *   __ICCARM__           // IAR ARM C-Compiler
 *   __IAR_SYSTEMS_ICC__  // for IAR Compiler
 *   __MICROBLAZE__       // Xilinx GCC Compiler for MicroBlaze
 *   _MSC_VER             // Microsoft Visual C++ Compiler
 *   __MINGW32__          // MINGW32 OS
 */

#pragma once

/**
 * 关于 inline 的差异
 */
#ifndef INLINE
    #if (defined __GNUC__) || (defined __ARMCC_VERSION) || (defined __ICCARM__) || (defined __MICROBLAZE__)
        #define INLINE inline
    #elif (defined _MSC_VER)
        #define INLINE __forceinline
    #else
        #define INLINE __inline
    #endif
#endif


/**
 * 关于 weak 定义的支持
 */
#if (defined __GNUC__) || (defined __ARMCC_VERSION)
    #define CCC_WEAK    __attribute__((weak))
#elif (defined __IAR_SYSTEMS_ICC__)
    #define CCC_WEAK    __weak
#elif (defined _MSC_VER)
    //#error "No support for weak define !"
    //#error "Try: #pragma weak"
    //#error "Try: __declspec(selectany)"
	#define CCC_WEAK
#else
    //#error "No support for weak define !"
	#define CCC_WEAK
#endif


// 关于 RAM CODE 声明
#if   (defined __ICCARM__)
	#define _RAMCODE_   __ramfunc
#elif (defined __ARMCC_VERSION)
	#define _RAMCODE_	__attribute__((section("ram_code")))
#else
	#define _RAMCODE_
#endif


/**
 * 关于动态库函数导出声明的支持
 * - 需要导出的函数应加上 CCDLLPUBLIC 声明
 * - 编译 DLL 时应定义 BUILDING_DLL 宏
 */
#if (defined _WIN32) || (defined __CYGWIN__)
    #ifdef BUILDING_DLL
        #ifdef __GNUC__
            #define CCDLLPUBLIC  __attribute__((dllexport))
        #else
            #define CCDLLPUBLIC  __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.
        #endif
    #else
        #ifdef __GNUC__
            #define CCDLLPUBLIC  __attribute__((dllimport))
        #else
            #define CCDLLPUBLIC  __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.
        #endif
    #endif
    #define CCDLLHIDDEN
#elif __GNUC__ >= 4
    #define CCDLLPUBLIC      __attribute__((visibility ("default")))
    #define CCDLLHIDDEN      __attribute__((visibility ("hidden")))
#else
    #define CCDLLPUBLIC
    #define CCDLLHIDDEN
#endif


/**
 * 关于 printf 中 format 的差异
 */
#define FMTD   int
#define FMTU   unsigned int
#define FMTLD  long
#define FMTLU  unsigned long
    
#if (defined __GNUC__) || (defined __ARMCC_VERSION) || (defined __ICCARM__) || (defined __MICROBLAZE__)
    #define FMTLLD long long int
    #define FMTLLU long long unsigned int
#elif (defined _MSC_VER)
    #define FMTLLD int64_t
    #define FMTLLU uint64_t
#else
    #define FMTLLD long long int
    #define FMTLLU long long unsigned int
#endif


/**
 * 关于类似 printf() 函数的声明 的差异
 */
#if (defined __GNUC__) || (defined __MICROBLAZE__)
    // extern void mylog(void *logger, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
#elif (defined __ARMCC_VERSION) || (defined __ICCARM__)
    // #pragma __printf_args
    // extern void mylog(void *logger, const char *fmt, ...);
#elif _MSC_VER
    // extern void mylog(void *logger, _Printf_format_string_ const char *fmt, ...);
#endif


 /**
 * 关于 stdint.h 中的差异
 */
#if (defined __GNUC__) || (defined __ARMCC_VERSION) || (defined __ICCARM__) || (defined __MICROBLAZE__)
    // OK
#elif _MSC_VER
    typedef unsigned int uint;
    #ifdef _WIN64
        typedef __int64 ssize_t;
    #else
        typedef __int   ssize_t;
    #endif
#endif


 /**
 * 关于 文件路径分隔符 的差异
 */
#ifdef _WIN32
    #define PATH_SEPARATOR '\\'
#else
    #define PATH_SEPARATOR '/'
#endif
